package com.wbcs.system.buttons;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wbcs.config.Config;
import com.wbcs.config.component.ComponentConfigLoadManager;
import com.wbcs.config.component.IComponentConfigBean;
import com.wbcs.config.component.application.report.ReportBean;
import com.wbcs.config.xml.XmlElementBean;
import com.wbcs.exception.WbcsConfigLoadingException;
import com.wbcs.exception.WbcsRuntimeWarningException;
import com.wbcs.system.CacheDataBean;
import com.wbcs.system.ReportRequest;
import com.wbcs.system.assistant.EditableReportAssistant;
import com.wbcs.system.component.application.report.EditableDetailReportType;
import com.wbcs.system.component.application.report.EditableDetailReportType2;
import com.wbcs.system.component.application.report.EditableListReportType;
import com.wbcs.system.component.application.report.EditableListReportType2;
import com.wbcs.system.component.application.report.abstractreport.AbsListReportType;
import com.wbcs.system.component.application.report.abstractreport.IEditableReportType;
import com.wbcs.system.component.application.report.configbean.editablereport.EditActionGroupBean;
import com.wbcs.system.component.application.report.configbean.editablereport.IEditableReportEditGroupOwnerBean;
import com.wbcs.system.component.application.report.configbean.editablereport.transaction.DefaultTransactionType;
import com.wbcs.system.intercept.AbsPageInterceptor;
import com.wbcs.system.serveraction.IServerAction;
import com.wbcs.util.Consts;

public class ServerSQLActionButton extends WbcsButton implements IServerAction,IEditableReportEditGroupOwnerBean
{
    private boolean shouldRefreshPage;

    private String beforeCallbackMethod;
    
    private String afterCallbackMethod;
    
    private String conditions;
    
    private String successprompt;
    
    private String failedprompt;
    
    private boolean isAutoReportdata=true;
    
    private EditableReportSQLButtonDataBean editDataBean;//<button/>效果与<delete/>类似，都不会影响到列的可编辑性
    
    public ServerSQLActionButton(IComponentConfigBean ccbean)
    {
        super(ccbean);
    }
    
    /*public String getButtonType()
    {
        return Consts_Private.SAVE_BUTTON;
    }*/

    @Override
	public String showButton(ReportRequest rrequest,String dynclickevent)
    {
        if(editDataBean==null||editDataBean.getLstEditActionGroupBeans()==null||editDataBean.getLstEditActionGroupBeans().size()==0) return "";
        return super.showButton(rrequest,getMyClickEvent(rrequest));
    }
    
    @Override
	public String showButton(ReportRequest rrequest,String dynclickevent,String button)
    {
        if(editDataBean==null||editDataBean.getLstEditActionGroupBeans()==null||editDataBean.getLstEditActionGroupBeans().size()==0) return "";
        return super.showButton(rrequest,getMyClickEvent(rrequest),button);
    }

    @Override
	public String showMenu(ReportRequest rrequest,String dynclickevent)
    {
        if(editDataBean==null||editDataBean.getLstEditActionGroupBeans()==null||editDataBean.getLstEditActionGroupBeans().size()==0) return "";
        return super.showMenu(rrequest,getMyClickEvent(rrequest));
    }

    private String getMyClickEvent(ReportRequest rrequest)
    {
        StringBuffer resultBuf=new StringBuffer();
        resultBuf.append("invokeServerActionForReportData('"+this.ccbean.getPageBean().getId()+"','"+this.ccbean.getId()+"','button");
        if(this.isAutoReportdata) resultBuf.append("_autoreportdata");
        resultBuf.append("{"+this.getName()+"}',");
        resultBuf.append(this.isAutoReportdata?this.conditions:"null");
        resultBuf.append(",null,"+this.shouldRefreshPage+","+this.beforeCallbackMethod+","+this.afterCallbackMethod+")");
        return resultBuf.toString();
    }
    
    public String executeSeverAction(ReportRequest rrequest,IComponentConfigBean ccbean,List<Map<String,String>> lstData,Map<String,String> mCustomizedData)
    {
        if(editDataBean==null) return "0";
        ReportBean rbean=(ReportBean)this.ccbean;
        CacheDataBean cdb=rrequest.getCdb(this.ccbean.getId());
        cdb.setLstEditedData(this.editDataBean,lstData);
        cdb.getAttributes().put("WX_UPDATE_CUSTOMIZEDATAS",mCustomizedData);//对于用户自定义的数据，都会存放在一个Map中，键为参数名；值为参数值
        cdb.setLstEditedParamValues(this.editDataBean,EditableReportAssistant.getInstance().getExternalValues(this.editDataBean,lstData,
                rbean,rrequest));
        rrequest.setTransactionObj(new DefaultTransactionType());
        List<ReportBean> lstSaveReportBeans=new ArrayList<ReportBean>();
        lstSaveReportBeans.add(rbean);
        List<AbsPageInterceptor> lstPageInterceptors=rrequest.getLstPageInterceptors();
        if(lstPageInterceptors!=null&&lstPageInterceptors.size()>0)
        {
            for(AbsPageInterceptor pageInterceptorObjTmp:lstPageInterceptors)
            {
                pageInterceptorObjTmp.doStartSave(rrequest,lstSaveReportBeans);
            }
        }
        List<EditActionGroupBean> lstAllEditActionGroupBeans=new ArrayList<EditActionGroupBean>();
        lstAllEditActionGroupBeans.addAll(this.editDataBean.getLstEditActionGroupBeans());
        if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().beginTransaction(rrequest,lstAllEditActionGroupBeans);
        Exception exception=null;
        try
        {
            if(rbean.getInterceptor()!=null)
            {
                rbean.getInterceptor().doSave(rrequest,rbean,this.editDataBean);
            }else
            {
                EditableReportAssistant.getInstance().doSaveReport(rbean,rrequest,this.editDataBean);
            }            
            if(lstPageInterceptors!=null&&lstPageInterceptors.size()>0)
            {
                AbsPageInterceptor pageInterceptorObjTmp;
                for(int i=lstPageInterceptors.size()-1;i>=0;i--)
                {
                    pageInterceptorObjTmp=lstPageInterceptors.get(i);
                    pageInterceptorObjTmp.doEndSave(rrequest,lstSaveReportBeans);
                }
            }
            if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().commitTransaction(rrequest,lstAllEditActionGroupBeans);
            if(this.successprompt!=null&&!this.successprompt.trim().equals(""))
            {
                rrequest.getWResponse().getMessageCollector().success(rrequest.getI18NStringValue(this.successprompt),false);
            }
        }catch(WbcsRuntimeWarningException wrwe)
        {
            if(rrequest.getTransactionWrapper()!=null)
            {
                if(rrequest.getWResponse().getStatecode()!=Consts.STATECODE_FAILED)
                {
                    rrequest.getTransactionWrapper().commitTransaction(rrequest,lstAllEditActionGroupBeans);
                }else
                {
                    rrequest.getTransactionWrapper().rollbackTransaction(rrequest,lstAllEditActionGroupBeans);
                    exception=wrwe;
                }
            }
            throw new WbcsRuntimeWarningException();
        }catch(Exception e)
        {
            exception=e;
            if(rrequest.getTransactionWrapper()!=null) rrequest.getTransactionWrapper().rollbackTransaction(rrequest,lstAllEditActionGroupBeans);
        }finally
        {
            rrequest.setTransactionObj(null);            
        }
        if(exception!=null)
        {
            rrequest.getWResponse().getMessageCollector().error(rrequest.getI18NStringValue(this.failedprompt),
                    "执行报表"+ccbean.getPath()+"下的按钮"+this.name+"配置的脚本失败",exception);
            return "-1";
        }else
        {
            return "1";
        }
    }
    
    public String executeServerAction(HttpServletRequest request,HttpServletResponse response,List<Map<String,String>> lstData)
    {
        return "";
    }
    
    @Override
	public void loadExtendConfig(XmlElementBean eleButtonBean)
    {
        super.loadExtendConfig(eleButtonBean);
        if(!(this.ccbean instanceof ReportBean))
        {
            throw new WbcsConfigLoadingException("组件"+this.ccbean.getPath()+"不是报表，不能配置执行脚本的按钮");
        }
        this.beforeCallbackMethod=eleButtonBean.attributeValue("beforecallbackmethod");
        if(this.beforeCallbackMethod!=null&&this.beforeCallbackMethod.trim().equals("")) this.beforeCallbackMethod=null;
        this.afterCallbackMethod=eleButtonBean.attributeValue("aftercallbackmethod");
        if(this.afterCallbackMethod!=null&&this.afterCallbackMethod.trim().equals("")) this.afterCallbackMethod=null;
        String refreshpage=eleButtonBean.attributeValue("refreshpage");
        refreshpage=refreshpage==null||refreshpage.trim().equals("")?"true":refreshpage.toLowerCase().trim();
        this.shouldRefreshPage=refreshpage.equals("true");
        String autoreportdata=eleButtonBean.attributeValue("autoreportdata");
        autoreportdata=autoreportdata==null?"":autoreportdata.toLowerCase().trim();
        this.isAutoReportdata=!autoreportdata.equals("false");
        if(this.isAutoReportdata&&Config.getInstance().getReportType(((ReportBean)this.ccbean).getType()) instanceof AbsListReportType)
        {
            this.conditions=eleButtonBean.attributeValue("conditions");
            this.conditions=this.conditions==null?"":this.conditions.trim();
            if(this.conditions.equals(""))
            {
                this.conditions="{name:'SELECTEDROW',value:true}";
            }else
            {
                if((!this.conditions.startsWith("{")||!this.conditions.endsWith("}"))
                        &&(!this.conditions.startsWith("[")||!this.conditions.endsWith("]")))
                {//不是{...}或[...]格式，则给它加上{}括住，构造正确的json字符串
                    this.conditions="{"+this.conditions+"}";
                }
            }
        }
        String successmess=eleButtonBean.attributeValue("successprompt");
        String failedmess=eleButtonBean.attributeValue("failedprompt");
        if(successmess!=null)
        {
            this.successprompt=Config.getInstance().getResourceString(null,this.ccbean.getPageBean(),successmess,false).trim();
        }else
        {
            this.successprompt="";
        }
        if(failedmess!=null)
        {
            this.failedprompt=Config.getInstance().getResourceString(null,this.ccbean.getPageBean(),failedmess,false).trim();
        }else
        {
            this.failedprompt="";
        }
        EditableReportSQLButtonDataBean sqlButtonDataBean=new EditableReportSQLButtonDataBean(this);
        sqlButtonDataBean.setAutoReportdata(isAutoReportdata);
        this.editDataBean=(EditableReportSQLButtonDataBean)ComponentConfigLoadManager.loadEditConfig(this,sqlButtonDataBean,eleButtonBean);
    }
    
    public ReportBean getReportBean()
    {
        return (ReportBean)this.ccbean;
    }
    
    private boolean hasDoPostLoad;
    
    @Override
	public void doPostLoad()
    {
        if(hasDoPostLoad) return;
        hasDoPostLoad=true;
        String reportTypeKey=null;
        if(this.isAutoReportdata)
        {
            if(!(Config.getInstance().getReportType(((ReportBean)this.ccbean).getType()) instanceof IEditableReportType))
            {
                throw new WbcsConfigLoadingException("组件"+this.ccbean.getPath()+"不是可编辑报表类型，在用<button/>直接配置更新脚本时不能采用自动获取报表数据传到后台的方式，需要将<button/>的autoreportdata配置为false");
            }
            IEditableReportType reportTypeObj=(IEditableReportType)Config.getInstance().getReportType(((ReportBean)this.ccbean).getType());
            if(reportTypeObj instanceof EditableDetailReportType)
            {
                reportTypeKey=EditableDetailReportType.KEY;
            }else if(reportTypeObj instanceof EditableDetailReportType2)
            {
                reportTypeKey=EditableDetailReportType2.KEY;
            }else if(reportTypeObj instanceof EditableListReportType)
            {
                reportTypeKey=EditableListReportType.KEY;
            }else if(reportTypeObj instanceof EditableListReportType2)
            {
                reportTypeKey=EditableListReportType2.KEY;
            }else
            {
                throw new WbcsConfigLoadingException("加载报表"+this.ccbean.getPath()+"上的更新数据的按钮失败，无效的可编辑报表类型");
            }
        }
        if(this.editDataBean.parseActionscripts(reportTypeKey)<=0) this.editDataBean=null;
    }
    
    private boolean hasDoPostLoadFinally;
    
    @Override
	public void doPostLoadFinally()
    {
        if(hasDoPostLoadFinally) return;
        hasDoPostLoadFinally=true;
        if(this.editDataBean!=null) this.editDataBean.setRealParamnamesInDoPostLoadFinally();
    }
    
    @Override
	public AbsButtonType clone(IComponentConfigBean ccbean)
    {
        ServerSQLActionButton buttonNew=(ServerSQLActionButton)super.clone(ccbean);
        if(this.editDataBean!=null)
        {
            buttonNew.editDataBean=(EditableReportSQLButtonDataBean)this.editDataBean.clone(buttonNew);
        }
        return buttonNew;
    }
}
